/**
 * 文章内容搜索
 */

var router = require('express').Router();
var userTool = require('../bin/user');
var articleTool = require('../bin/article');
var dbentityTool = require('../bin/dbentity');
var datetimeTool = require('../bin/util/datetime');
var assertAlljs = require('../bin/util/assert-alljs');
var fs = require('fs');

var matchProcess = function(text, regex, preLen, sucLen, preInsert, sucInsert){
    let searchText = text;
    let searchPos = 0;
    let match = 1;
    let briefText = '';
    let firstMatch = true;
    do{
        searchText = searchText.substr(searchPos);
        match = searchText.match(regex);
        if (match){
            searchPos = match.index + match[0].length;
            if (firstMatch){ // 第一次匹配，不用考虑上一次匹配后面的留长
                briefText += match.index > preLen ? ('......' + searchText.substring(match.index-preLen, match.index)) : searchText.substring(0, match.index);
            } else { // 第二~N次匹配，考虑上一次匹配后面的留长
                briefText += match.index > (sucLen+preLen) ? (searchText.substring(0, sucLen) + '......' + searchText.substring(match.index-preLen, match.index)) : searchText.substring(0, match.index);
            }
            briefText += preInsert + match[0] + sucInsert;
            firstMatch = false;
        }
    }while(match);
    if (firstMatch){ // 没有被匹配过，直接拷贝过来
        briefText = null;
    }else{ // 补齐最后一次匹配后面的留长
        briefText += searchText.length > sucLen ? (searchText.substring(0, sucLen) + '......') : searchText;
    }
    return {matched:!firstMatch, briefText};
};

router.get('/search(.*)?', async function(req, res){
    let assert = assertAlljs(req, res);

    if (await assert(userTool.check(req.session.user)))
        return;
	
	let fromtime = req.query.fromtime || '';
	let totime = req.query.totime || '';

    let filter = {};
    if (fromtime!=='')
        filter.produceTime = {$gt:datetimeTool.fromLocalString(fromtime)};
    
    if (totime!=='')
        filter.produceTime = {$lt:datetimeTool.fromLocalString(totime)};

    if (res.locals.blockRoot !== '')
        filter.mainclass = { $regex: '^('+res.locals.blockRoot+'(/.*)?)?$' };

    let isAdmin = 'user' in req.session && (req.session.user.role === 'admin' || req.session.user.role === 'admin:'+res.locals.blockRoot);
    if (!isAdmin)
        filter.status = {$ne:1};

    if (typeof(req.query.text)!=='string'){
        res.render('dyn.search.html', {isAdmin, fromtime, totime, text:req.query.text, articles:[]});
        return;
    }

    if (await assert(typeof(req.query.text)!=='string' || req.query.text.match(/^\s*$/), '必须有关键词且不得为空白'))
        return;

    let docs = await dbentityTool.find('article', filter);
    if (await assert(docs instanceof Error))
        return;

    let regex = req.query.text;
    let idx = 1;
    while (idx < regex.length){
        regex = regex.slice(0, idx) + '\\s?' + regex.slice(idx);
        idx+=4;
    }
    regex = new RegExp(regex, 'i');
    let matchDocs = [];
    for (let doc of docs){
        let matched = false;
        if (doc.title) {
            let result = matchProcess(doc.title, regex, 100, 100, '<b style="color:darkred">', '</b>');
            if (result.matched) {
                matched = true;
                doc.title = result.briefText;
            }
        }
        if (doc.author){
            let result = matchProcess(doc.author, regex, 100, 100, '<b style="color:darkred">', '</b>');
            if (result.matched){
                matched = true;
                doc.author = result.briefText;
            }
        }
        if (doc.produceUser && doc.produceUser.nickname){
            let result = matchProcess(doc.produceUser.nickname, regex, 100, 100, '<b style="color:darkred">', '</b>');
            if (result.matched){
                matched = true;
                doc.produceUser.nickname = result.briefText;
            }
        }

        let fileContentText = null;
        try{
            fileContentText = fs.readFileSync('data/html/' + doc._id + '.txt').toString();
        }catch (err) {
            continue;
        }
        if (fileContentText){
            let result = matchProcess(fileContentText, regex, 10, 5, '<b style="color:darkred">', '</b>');
            if (result.matched){
                matched = true;
                doc.brief = result.briefText;
            }
            if (matched)
                matchDocs.push(doc);
        }
    }

    let local = { isAdmin, fromtime, totime, text:req.query.text, articles : matchDocs.map((doc) => {
            let article = articleTool.toLocal(doc);
            articleTool.setBadge(article);
            if (typeof(article.publish) === 'number')
                article.publish = datetimeTool.to_yMdHm(article.publish).substr(5);
            return article;
        })
    };

    res.render('dyn.search.html', local);
});

module.exports = router;